package com.tgy.JUC.ForkJoin;

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

/***
 * @ClassName: ForkJoinDemo
 * @Description: 测试ForkJoin 双端队列
 * @Auther: 送你一块二向箔
 * @Date: 9:50 2022/3/15
 * @version : V1.0
 */
public class ForkJoinDemo {
    public static void main(String[] args) {

        run1();//6368
        run2();//924
        run3();//242
    }

    public static void run1() {
        long time1 = System.currentTimeMillis();
        Long sum = 0L;
        for (Long i = 0L; i <= 10_0000_0000; i++) {
            sum += i;
        }
        System.out.println(sum);
        long time2 = System.currentTimeMillis();
        System.out.println("时间消费" + (time2 - time1) + "ms");

    }

    public static void run2() {
        long time1 = System.currentTimeMillis();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        //forkJoinPool.execute(new TForkToinTask(1L,10_0000_0000L));//提交任务无返回值
        ForkJoinTask<Long> submit = forkJoinPool.submit(new TForkToinTask(0L, 10_0000_0000L));//提交任务，有返回值
        try {
            long aLong = submit.get();
            System.out.println(aLong);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        long time2 = System.currentTimeMillis();
        System.out.println("时间消费" + (time2 - time1) + "ms");

    }

    public static void run3() {
        long time1 = System.currentTimeMillis();

        //Stream并行流
        long reduce = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);
        System.out.println(reduce);
        long time2 = System.currentTimeMillis();
        System.out.println("时间消费" + (time2 - time1) + "ms");

    }

    static class TForkToinTask extends RecursiveTask<Long> {
        private long start;
        private long end;

        //临界值
        private long tmp = 10000L;

        public TForkToinTask(long start, long end) {
            this.start = start;
            this.end = end;
        }
        @Override
        protected Long compute() {

            if ((end - start) < tmp) {
                long sum = 0L;
                for (long i = start; i <= end; i++) {
                    sum += i;
                }
                return sum;
            } else {//递归思想
                long mid = (start + end) / 2;
                TForkToinTask forkjoin = new TForkToinTask(start, mid);
                forkjoin.fork();//拆分任务，把任务压入线程队列
                TForkToinTask forkjoin1 = new TForkToinTask(mid + 1, end);
                forkjoin1.fork();//拆分任务，把任务压入线程队列
                return forkjoin.join() + forkjoin1.join();
            }
        }
    }
}


